﻿/*
 * @Autor: PK
 * @Date: 2021-03-31 16:29:01
 * @Description: Customer复制时使用，可在Station中用来复制上一个顾客，多用于Schedule下一个Customer
 */

using System;
using System.Collections.Generic;
using O2DESNet.Distributions;
using ShkSimulation.core.exceptions;
using ShkSimulation.core.template.agency;
using ShkSimulation.core.template.customer;
using ShkSimulation.carsharing.impl.elements;

namespace ShkSimulation.carsharing.impl.create {
    
    public class TravelerTemplate : CloneableCustomerTemplate {
        
        private string uniqueKey;
        
        private Traveler travelerModel;
        private readonly Random random;

        private List<Agency> AgencyChain { get; set; }
        
        public string UniqueKey {
            get => uniqueKey;
        }

        public double Demand { get; set; }
        public TimeSpan DemandTimeSpan { get; set; }
        public bool InitWhenStart { get; set; }

        public TravelerTemplate(int id, List<Agency> agencies) {
            if (agencies == null || agencies.Count < 3) {
                throw new ErrorParamException("顾客服务链为空或小于3");
            }

            AgencyChain = agencies;
            travelerModel = new Traveler();
            travelerModel.SetAgenciesAndCloneAgencies(AgencyChain);
            travelerModel.Identify = $"需求{id}的顾客" + agencies[0].Name.Substring(0, 2)
                                          + "-"
                                          + agencies[1].Name.Substring(0, 2) 
                                          + "-"
                                          + agencies[2].Name.Substring(0, 2);
            uniqueKey = travelerModel.Identify;
            travelerModel.Id = id;
            random = new Random();
        }

        public Customer CreateCustomer() {
            Traveler traveler = new Traveler(), origin = travelerModel;
            traveler.Identify = origin.Identify;
            traveler.Id = origin.Id;
            traveler.SetAgenciesAndCloneAgencies(origin.GetAgencies());
            return traveler;
        }

        public DateTime GetCreateTimeAndPassNext(DateTime clockTime) {
            // TimeSpan span =  Exponential.Sample(random, TimeSpan.FromHours(1 / GetArriveRate(clockTime)));
            TimeSpan span = Exponential.Sample(random, DemandTimeSpan);
            return clockTime + span;
        }

        public List<Agency> GetCustomerAgencies() {
            return new List<Agency>(AgencyChain);
        }

        public Customer CloneCustomer(Customer customer) {
            AbstractTraveler traveler = new Traveler(), origin = customer as Traveler;
            traveler.Identify = origin.Identify;
            traveler.Id = origin.Id;
            traveler.SetAgenciesAndCloneAgencies(origin.GetAgencies());
            return traveler;
        }

    }
}
